#include <limits>
#include "unifiedMathFunctions.hpp"

namespace hms
{

/** @brief Overload for usage with cell and fields
 * @overload */
template<typename CellType, typename MeshType>
scalar courantTimeStep(
	const CellType& cell,
	const Field<MeshType>& v,
	const Field<MeshType>& d
){
	return courantTimeStep(
		cell.area(), cell.circumf(),
		v.values().col( cell.index() ),
		d.values()( 0, cell.index() )
	);
}

/**
 * @brief Returns an eigen condition type which is true for supercritical
 * entries and false otherwise.
 * 
 * @tparam Derived1 
 * @tparam Derived2 
 * @param v 
 * @param d 
 * @return decltype(auto) 
 */
template<typename Derived1, typename Derived2>
decltype(auto) isSupercritical(
	const Eigen::DenseBase<Derived1>& v,
	const Eigen::DenseBase<Derived2>& d
){
	// return v.derived().colwise().norm() >= sqrt(phys::g * d.derived());
	return v.derived().colwise().squaredNorm() > phys::g * d.derived();
}


/** @brief Returns shallow water wave speed
 * 
 * Equation: c_W = sqrt(g*d) */
template<typename D>
auto wavespeed( const D& d ) -> decltype(auto)
{
	using std::sqrt;
	using Eigen::sqrt;
	assert( notNegative(d) );
	return sqrt( phys::g * d );
}

} // end namespace hms
